package com.jinzhi.jzweb.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.jinzhi.common.base.CoreServiceImpl;
import com.jinzhi.common.service.DictService;
import com.jinzhi.common.utils.Result;
import com.jinzhi.common.utils.StringUtil;
import com.jinzhi.jzweb.dao.TrackDrawDao;
import com.jinzhi.jzweb.domain.TrackDrawDO;
import com.jinzhi.jzweb.domain.TrackDrawDownLoadDO;
import com.jinzhi.jzweb.service.TrackDrawService;
import com.jinzhi.jzweb.utils.CustomerDailyImportListener2;
import com.jinzhi.jzweb.utils.StringConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 * <pre>
 * 赛道抽签表（存储抽签信息）
 * </pre>
 * <small> 2024-02-28 09:32:18 | lance</small>
 */
@Service
public class TrackDrawServiceImpl extends CoreServiceImpl<TrackDrawDao, TrackDrawDO> implements TrackDrawService {
    @Autowired
    private DictService dictService;

    //查询抽签规则
    public String getRule(){
        Map<String, String> map = new HashMap<>();
        map.put("name", "draw_rule");
        map.put("type", "draw_rule");
        return dictService.selDicBy(map);
    }

    /**
     * 抽签接口
     * @param trackDrawDTO
     * @return
     */
    @Override
    public Result<List<TrackDrawDO>> trackDrawList(TrackDrawDO trackDrawDTO) {
        if (trackDrawDTO.getCbatchId()==null){
            return Result.fail("请先选择抽签批次！");
        }
        //获取检录号规则
        //String rule = getRule();
        Random random = new Random();
        //获取抽签列表
        LinkedList<String> numList = new LinkedList<>();
        Wrapper<TrackDrawDO> wrapper = new EntityWrapper<>();
        wrapper.eq("cbatch_id",trackDrawDTO.getCbatchId());
        wrapper.orderBy(true,"sort");
        List<TrackDrawDO> trackDrawDOS = this.selectList(wrapper);

        // 使用 Stream API 过滤出 placeNum 不为空的元素
        List<TrackDrawDO> filteredList = trackDrawDOS.stream()
                .filter(trackDrawDO -> trackDrawDO.getPlaceNum() != null && !trackDrawDO.getPlaceNum().isEmpty())
                .collect(Collectors.toList());

        // 判断是否进行导入学校
        if (trackDrawDOS.size()<=0) {
            return Result.fail("请先导入学校！");
        }
        // 将查询到的学校放入抽签列表中
        for (int i = 1; i <= trackDrawDOS.size(); i++) {
            numList.add(String.valueOf(i));
        }
        // 将指定的检录号从数组中移除
        filteredList.forEach(trackDrawDO ->{
            if(StringUtil.notEmpty(trackDrawDO.getPlaceNum())){
                numList.remove(trackDrawDO.getPlaceNum());
            }
        });

        //打乱一下存放检录号的列表
        Collections.shuffle(numList,random);
        // 遍历设置检录号
        for (TrackDrawDO record : trackDrawDOS) {
            String recordNumber = "";
            Integer recordNumberSort=null;
            //判断检录序号是否需要固定
            if(StringUtil.notEmpty(record.getPlaceNum())){
                recordNumberSort= Integer.valueOf(record.getPlaceNum());
                //recordNumber=rule+record.getPlaceNum();
                recordNumber=record.getPlaceNum();
                record.setRecordNumberSort(Integer.parseInt(record.getPlaceNum()));
                numList.remove(record.getPlaceNum());
            }else{
                recordNumberSort= Integer.valueOf(numList.getFirst());
                //recordNumber=rule+numList.getFirst();
                recordNumber=numList.getFirst();
                record.setRecordNumberSort(Integer.parseInt(numList.getFirst()));
                numList.removeFirst();
            }
            //设置检录号
            record.setRecordNumber(recordNumber);
            record.setRecordNumberSort(recordNumberSort);

        }
        if(null!=trackDrawDOS && !trackDrawDOS.isEmpty()){
            this.updateBatchById(trackDrawDOS);
        }

        return Result.ok(setTemplate(trackDrawDOS));

    }

    /**
     * 查询上一次的抽签结果
     * @param trackDrawDTO
     * @return
     */
    @Override
    @Transactional
    public Result<List<TrackDrawDO>> trackList(TrackDrawDO trackDrawDTO) {
        if (trackDrawDTO.getCbatchId()==null){
            return Result.fail("请先选择抽签批次！");
        }
        //存储抽签你信息
        boolean hasDraw = true;//默认为true.不存在上次抽签结果时改为false

        //查询上一次的抽签结果
        Wrapper<TrackDrawDO> wrapper = new EntityWrapper<>();
        wrapper.eq("cbatch_id",trackDrawDTO.getCbatchId());
        wrapper.orderBy(true,"sort");
        List<TrackDrawDO> trackDrawDOS = this.selectList(wrapper);

        //如果没有抽签上一次抽签结果那就默认初始化
        if(trackDrawDOS==null || trackDrawDOS.size()==0){
            trackDrawDOS = new ArrayList<>();
            hasDraw = false;
            return Result.ok(trackDrawDOS);
        }else {
            if (trackDrawDOS.get(0).getRecordNumber()==null) {
                hasDraw = false;
            }
        }
        int size = trackDrawDOS.size();
        List<TrackDrawDO> trackDrawDOS1 = setTemplate(trackDrawDOS);
        trackDrawDOS1.get(0).setHasDraw(hasDraw);
        trackDrawDOS1.get(0).setTotal(size);
        return Result.ok(trackDrawDOS1);
    }


    /**
     * 导入抽签参赛院校
     *
     * @param file
     * @return
     */
    @Override
    public Result<Object> importExcelTrackDraw(MultipartFile file,Long cbatchId) {
        if (cbatchId==null){
            return Result.fail("请先选择导入抽签批次！");
        }
        List<TrackDrawDownLoadDO> lottery = new ArrayList<>();
        if (!"application/vnd.ms-excel".equals(file.getContentType())) {
            return Result.fail("文件格式错误，请选择.xls文件");
        }
        try {
            InputStream inputStream = file.getInputStream();
            lottery = EasyExcel.read(inputStream)
                    // 这个转换是成全局的， 所有java为string,excel为string的都会用这个转换器。
                    // 如果就想单个字段使用请使用@ExcelProperty 指定converter
                    .registerConverter(new StringConverter())
                    // 注册监听器，可以在这里校验字段
                    .registerReadListener(new CustomerDailyImportListener2())
                    .head(TrackDrawDownLoadDO.class)
                    .sheet()
                    .headRowNumber(2)
                    .doReadSync();
        } catch (Exception e) {
            e.getMessage();
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }
        if (lottery.isEmpty()) {
            return Result.fail("Excel数据为空，请检查");
        }
        boolean b = true;
        // 查询是否进行过导入
        List<TrackDrawDO> trackDrawDOS = this.selectList(new EntityWrapper<TrackDrawDO>()
                .eq("cbatch_id",cbatchId)
                .orderBy("sort", true));
        // 为空没进行导入，将数据插入到数据库
        if (trackDrawDOS.isEmpty()) {
            for (int i = 0; i < lottery.size(); i++) {
                TrackDrawDO trackDrawDO = new TrackDrawDO();
                trackDrawDO.setSort(i+1);
                trackDrawDO.setCbatchId(cbatchId);
                trackDrawDO.setUnitName(lottery.get(i).getUnitName());
                trackDrawDOS.add(trackDrawDO);
            }
            b = this.insertBatch(trackDrawDOS);
        }else{
            // 导入后新增的学校
            List<TrackDrawDO> trackDrawDOS1=new ArrayList<>();
            // 获取导入后的最大排序数
            Integer sort = trackDrawDOS.get(trackDrawDOS.size() - 1).getSort();
            // 进行过导入，校验是否重复
            for (int i = 0; i < lottery.size(); i++) {
                TrackDrawDO trackDrawDO = new TrackDrawDO();
                for (int j = 0; j < trackDrawDOS.size(); j++) {
                    if (lottery.get(i).getUnitName().equals(trackDrawDOS.get(j).getUnitName())) {
                        return Result.fail("第" + (i+1) + "行参赛学校已存在，请检查");
                    }
                }
                // 设置排序数量
                trackDrawDO.setSort(sort+1);
                sort++;
                // 设置学校名称
                trackDrawDO.setUnitName(lottery.get(i).getUnitName());
                trackDrawDO.setCbatchId(cbatchId);
                trackDrawDOS1.add(trackDrawDO);
            }
            b=this.insertBatch(trackDrawDOS1);
        }

        return b?Result.ok():Result.fail();
    }

    /**
     * 处理抽签结果数据，改成4*18格式
     */
    public List<TrackDrawDO> setTemplate(List<TrackDrawDO> trackDrawDOS){
        List<TrackDrawDO> trackDrawDOSCopy = new ArrayList<>();//存储最终的抽签结果

        //存储每一行的抽签结果
        TrackDrawDO trackDrawDO1 = new TrackDrawDO();
        List<TrackDrawDO> trackDrawDOSO1 = new ArrayList<>();
        for (int i = 0; i < trackDrawDOS.size(); i++) {
            trackDrawDOSO1.add(trackDrawDOS.get(i));
            if((i+1) % 4 == 0){
                trackDrawDO1.setTrackDrawDOList(trackDrawDOSO1);
                trackDrawDOSCopy.add(trackDrawDO1);
                //清空
                trackDrawDO1 = new TrackDrawDO();
                trackDrawDOSO1 = new ArrayList<>();
            } else if (trackDrawDOS.size()-(i+1)==0) {
                trackDrawDO1.setTrackDrawDOList(trackDrawDOSO1);
                trackDrawDOSCopy.add(trackDrawDO1);
            }
        }
        return trackDrawDOSCopy;
    }

}


